﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace IVS.Calculator
{
    /// <summary>
    /// Interaction logic for MainWindow.
    /// </summary>
    public partial class MainWindowView : Form
    {
        #region ------------------------------ CONSTRUCTION ------------------------------

        public MainWindowView ()
        {
            InitializeComponent();
        }

        #endregion

        #region ------------------------------ FIELDS ------------------------------



        #endregion

        #region ------------------------------ PROPERTIES ------------------------------

        /// <summary>
        /// Gets presenter class associated with this view.
        /// </summary>
        public MainWindowPresenter Presenter { get; private set; }

        #endregion

        #region ------------------------------ PUBLIC METHODS ------------------------------

        /// <summary>
        /// Imports presenter associated with this view.
        /// </summary>
        /// <param name="presenter">the presenter</param>
        public void ImportPresenter (MainWindowPresenter presenter)
        {
            Presenter = presenter;
            Presenter.DisplayChanged += OnDisplayChanged;
        }


        #endregion

        #region ------------------------------ PRIVATE METHODS ------------------------------

        /// <summary>
        /// Callback of DisplayChanged event from presenter layer.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnDisplayChanged (object sender, EventArgs e)
        {
            displayBox.Text = Presenter.Display;
        }

        /// <summary>
        /// Removes highlight from all binary operation buttons
        /// except buttons declared as arguments.
        /// </summary>
        /// <param name="buttons">buttons to not set</param>
        private void RemoveHighlight (params Button[] buttons)
        {
            if (!buttons.Contains(button_plus))
                button_plus.ForeColor = Color.Black;
            
            if (!buttons.Contains(button_minus))
                button_minus.ForeColor = Color.Black;
            
            if (!buttons.Contains(button_mul))
                button_mul.ForeColor = Color.Black;
            
            if (!buttons.Contains(button_div))
                button_div.ForeColor = Color.Black;
            
            if (!buttons.Contains(button_pow))
                button_pow.ForeColor = Color.Black;
        }

        /// <summary>
        /// Sets memory flag to given value.
        /// </summary>
        /// <param name="isSet">indicates, whether the memory flag is set or not</param>
        private void SetMemoryFlag (bool isSet)
        {
            if (isSet)
                label_memFlag.Text = "M";
            else
                label_memFlag.Text = "";
        }

        /// UI EVENT CALLBACKS

        // NUMBER BUTTONS

        private void button_0_Click (object sender, EventArgs e)
        {
            Presenter.HandleNumberButton('0');
        }

        private void button_1_Click (object sender, EventArgs e)
        {
            Presenter.HandleNumberButton('1');
        }

        private void button_2_Click (object sender, EventArgs e)
        {
            Presenter.HandleNumberButton('2');
        }

        private void button_3_Click (object sender, EventArgs e)
        {
            Presenter.HandleNumberButton('3');
        }

        private void button_4_Click (object sender, EventArgs e)
        {
            Presenter.HandleNumberButton('4');
        }

        private void button_5_Click (object sender, EventArgs e)
        {
            Presenter.HandleNumberButton('5');
        }

        private void button_6_Click (object sender, EventArgs e)
        {
            Presenter.HandleNumberButton('6');
        }

        private void button_7_Click (object sender, EventArgs e)
        {
            Presenter.HandleNumberButton('7');
        }

        private void button_8_Click (object sender, EventArgs e)
        {
            Presenter.HandleNumberButton('8');
        }

        private void button_9_Click (object sender, EventArgs e)
        {
            Presenter.HandleNumberButton('9');
        }

        private void button_point_Click (object sender, EventArgs e)
        {
            Presenter.HandleCommaButton();
        }


        // MATH FUNCTION BUTTONS

        private void button_plus_Click (object sender, EventArgs e)
        {
            Presenter.HandleOperatorButton(Operations.Addition);
            button_plus.ForeColor = Color.Red;
            
            // stop highlight other buttons
            RemoveHighlight(button_plus);
        }

        private void button_minus_Click (object sender, EventArgs e)
        {
            Presenter.HandleOperatorButton(Operations.Subtraction);
            button_minus.ForeColor = Color.Red;

            // stop highlight other buttons
            RemoveHighlight(button_minus);
        }

        private void button_mul_Click (object sender, EventArgs e)
        {
            Presenter.HandleOperatorButton(Operations.Multiplication);
            button_mul.ForeColor = Color.Red;

            // stop highlight other buttons
            RemoveHighlight(button_mul);
        }

        private void button_div_Click (object sender, EventArgs e)
        {
            Presenter.HandleOperatorButton(Operations.Division);
            button_div.ForeColor = Color.Red;

            // stop highlight other buttons
            RemoveHighlight(button_div);
        }

        private void button_pow_Click (object sender, EventArgs e)
        {
            Presenter.HandleOperatorButton(Operations.Power);
            button_pow.ForeColor = Color.Red;

            // stop highlight other buttons
            RemoveHighlight(button_pow);
        }

        private void button_sqrt_Click (object sender, EventArgs e)
        {
            Presenter.HandleOperatorButton(Operations.SquareRoot);
        }

        private void button_factorial_Click (object sender, EventArgs e)
        {
            Presenter.HandleOperatorButton(Operations.Factorial);
        }

        private void button_invert_Click (object sender, EventArgs e)
        {
            Presenter.HandleOperatorButton(Operations.Inversion);
        }

        private void button_negate_Click (object sender, EventArgs e)
        {
            Presenter.HandleOperatorButton(Operations.Negation);
        }


        // SPECIAL BUTTONS

        private void button_result_Click (object sender, EventArgs e)
        {
            Presenter.ShowResult();
            RemoveHighlight();
        }

        private void button_clear_Click (object sender, EventArgs e)
        {
            Presenter.ClearDisplay();
            RemoveHighlight();
        }

        private void button_memStore_Click (object sender, EventArgs e)
        {
            Presenter.StoreToMemory();
            RemoveHighlight();
            SetMemoryFlag(true);
        }

        private void button_memClear_Click (object sender, EventArgs e)
        {
            Presenter.ClearMemory();
            RemoveHighlight();
            SetMemoryFlag(false);
        }

        private void button_memRecall_Click (object sender, EventArgs e)
        {
            Presenter.ShowMemory();
            RemoveHighlight();
        }

        private void button_memAdd_Click (object sender, EventArgs e)
        {
            Presenter.AddToMemory();
            RemoveHighlight();
            SetMemoryFlag(true);
        }

        private void button_memSub_Click (object sender, EventArgs e)
        {
            Presenter.SubtractFromMemory();
            RemoveHighlight();
            SetMemoryFlag(true);
        }

        #endregion

        #region ------------------------------ EVENTS ------------------------------

        #endregion
    }
}
